﻿/******************************************************************************
	Cobalt - utility libraries for building XNA games
	Copyright (C) 2008 Philip Djonov

	This program is free software; you can redistribute it and/or modify it
	under the terms of the GNU General Public License as published by the Free
	Software Foundation; either version 2 of the License, or (at your option)
	any later version.

	This program is distributed in the hope that it will be useful, but
	WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
	or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
	for more details.

	You should have received a copy of the GNU General Public License along
	with this program; if not, write to the
	
		Free Software Foundation, Inc.
		51 Franklin Street, Fifth Floor
		Boston, MA  02110-1301, USA.
******************************************************************************/

using System;
using System.Collections.Generic;

using Microsoft.Xna.Framework.Content;

namespace Cobalt.Framework
{

	public struct RollingValue
	{
		private float baseVal, targetVal;
		private TimeSpan baseTime, targetTime;

		public float BaseValue { get { return baseVal; } }
		public float TargetValue { get { return targetVal; } }

		public TimeSpan BaseTime { get { return baseTime; } }
		public TimeSpan TargetTime { get { return targetTime; } }

		public RollingValue( float value )
		{
			baseVal = value;
			targetVal = value;

			baseTime = TimeSpan.Zero;
			targetTime = TimeSpan.Zero;
		}

		public static readonly TimeSpan DefaultRollTime = TimeSpan.FromTicks( 200 * TimeSpan.TicksPerMillisecond );

		public void Set( float target, TimeSpan now, TimeSpan rollTime )
		{
			baseVal = targetVal;
			baseTime = now;

			targetVal = target;
			targetTime = now + rollTime;
		}

		public void Set( float target, TimeSpan now )
		{
			Set( target, now, DefaultRollTime );
		}

		public void AddDelta( float delta, TimeSpan now, TimeSpan rollTime )
		{
			Set( targetVal + delta, now, rollTime );
		}

		public void AddDelta( float delta, TimeSpan now )
		{
			AddDelta( delta, now, DefaultRollTime );
		}

		public void AddDelta( float delta, float min, float max, TimeSpan now, TimeSpan rollTime )
		{
			AddDelta( Helpers.Clamp( targetVal + delta, min, max ), now, rollTime );
		}

		public void AddDelta( float delta, float min, float max, TimeSpan now )
		{
			AddDelta( delta, min, max, now, DefaultRollTime );
		}

		public float Evaluate( TimeSpan at )
		{
			if( at >= targetTime )
				return targetVal;
			if( at <= baseTime )
				return baseVal;

			float t = (float)((at - baseTime).TotalMilliseconds /
				(targetTime - baseTime).TotalMilliseconds);
			return baseVal + (targetVal - baseVal) * t;
		}
	}

}